home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / sparc / include / asm / pgtable_64.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  23.7 KB  |  778 lines

  1. /*
  2.  * pgtable.h: SpitFire page table operations.
  3.  *
  4.  * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
  5.  * Copyright 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  6.  */
  7.  
  8. #ifndef _SPARC64_PGTABLE_H
  9. #define _SPARC64_PGTABLE_H
  10.  
  11. /* This file contains the functions and defines necessary to modify and use
  12.  * the SpitFire page tables.
  13.  */
  14.  
  15. #include <asm-generic/pgtable-nopud.h>
  16.  
  17. #include <linux/compiler.h>
  18. #include <linux/const.h>
  19. #include <asm/types.h>
  20. #include <asm/spitfire.h>
  21. #include <asm/asi.h>
  22. #include <asm/system.h>
  23. #include <asm/page.h>
  24. #include <asm/processor.h>
  25.  
  26. /* The kernel image occupies 0x4000000 to 0x6000000 (4MB --> 96MB).
  27.  * The page copy blockops can use 0x6000000 to 0x8000000.
  28.  * The TSB is mapped in the 0x8000000 to 0xa000000 range.
  29.  * The PROM resides in an area spanning 0xf0000000 to 0x100000000.
  30.  * The vmalloc area spans 0x100000000 to 0x200000000.
  31.  * Since modules need to be in the lowest 32-bits of the address space,
  32.  * we place them right before the OBP area from 0x10000000 to 0xf0000000.
  33.  * There is a single static kernel PMD which maps from 0x0 to address
  34.  * 0x400000000.
  35.  */
  36. #define    TLBTEMP_BASE        _AC(0x0000000006000000,UL)
  37. #define    TSBMAP_BASE        _AC(0x0000000008000000,UL)
  38. #define MODULES_VADDR        _AC(0x0000000010000000,UL)
  39. #define MODULES_LEN        _AC(0x00000000e0000000,UL)
  40. #define MODULES_END        _AC(0x00000000f0000000,UL)
  41. #define LOW_OBP_ADDRESS        _AC(0x00000000f0000000,UL)
  42. #define HI_OBP_ADDRESS        _AC(0x0000000100000000,UL)
  43. #define VMALLOC_START        _AC(0x0000000100000000,UL)
  44. #define VMALLOC_END        _AC(0x0000000200000000,UL)
  45. #define VMEMMAP_BASE        _AC(0x0000000200000000,UL)
  46.  
  47. #define vmemmap            ((struct page *)VMEMMAP_BASE)
  48.  
  49. /* XXX All of this needs to be rethought so we can take advantage
  50.  * XXX cheetah's full 64-bit virtual address space, ie. no more hole
  51.  * XXX in the middle like on spitfire. -DaveM
  52.  */
  53. /*
  54.  * Given a virtual address, the lowest PAGE_SHIFT bits determine offset
  55.  * into the page; the next higher PAGE_SHIFT-3 bits determine the pte#
  56.  * in the proper pagetable (the -3 is from the 8 byte ptes, and each page
  57.  * table is a single page long). The next higher PMD_BITS determine pmd#
  58.  * in the proper pmdtable (where we must have PMD_BITS <= (PAGE_SHIFT-2)
  59.  * since the pmd entries are 4 bytes, and each pmd page is a single page
  60.  * long). Finally, the higher few bits determine pgde#.
  61.  */
  62.  
  63. /* PMD_SHIFT determines the size of the area a second-level page
  64.  * table can map
  65.  */
  66. #define PMD_SHIFT    (PAGE_SHIFT + (PAGE_SHIFT-3))
  67. #define PMD_SIZE    (_AC(1,UL) << PMD_SHIFT)
  68. #define PMD_MASK    (~(PMD_SIZE-1))
  69. #define PMD_BITS    (PAGE_SHIFT - 2)
  70.  
  71. /* PGDIR_SHIFT determines what a third-level page table entry can map */
  72. #define PGDIR_SHIFT    (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS)
  73. #define PGDIR_SIZE    (_AC(1,UL) << PGDIR_SHIFT)
  74. #define PGDIR_MASK    (~(PGDIR_SIZE-1))
  75. #define PGDIR_BITS    (PAGE_SHIFT - 2)
  76.  
  77. #ifndef __ASSEMBLY__
  78.  
  79. #include <linux/sched.h>
  80.  
  81. /* Entries per page directory level. */
  82. #define PTRS_PER_PTE    (1UL << (PAGE_SHIFT-3))
  83. #define PTRS_PER_PMD    (1UL << PMD_BITS)
  84. #define PTRS_PER_PGD    (1UL << PGDIR_BITS)
  85.  
  86. /* Kernel has a separate 44bit address space. */
  87. #define FIRST_USER_ADDRESS    0
  88.  
  89. #define pte_ERROR(e)    __builtin_trap()
  90. #define pmd_ERROR(e)    __builtin_trap()
  91. #define pgd_ERROR(e)    __builtin_trap()
  92.  
  93. #endif /* !(__ASSEMBLY__) */
  94.  
  95. /* PTE bits which are the same in SUN4U and SUN4V format.  */
  96. #define _PAGE_VALID      _AC(0x8000000000000000,UL) /* Valid TTE            */
  97. #define _PAGE_R            _AC(0x8000000000000000,UL) /* Keep ref bit uptodate*/
  98.  
  99. /* SUN4U pte bits... */
  100. #define _PAGE_SZ4MB_4U      _AC(0x6000000000000000,UL) /* 4MB Page             */
  101. #define _PAGE_SZ512K_4U      _AC(0x4000000000000000,UL) /* 512K Page            */
  102. #define _PAGE_SZ64K_4U      _AC(0x2000000000000000,UL) /* 64K Page             */
  103. #define _PAGE_SZ8K_4U      _AC(0x0000000000000000,UL) /* 8K Page              */
  104. #define _PAGE_NFO_4U      _AC(0x1000000000000000,UL) /* No Fault Only        */
  105. #define _PAGE_IE_4U      _AC(0x0800000000000000,UL) /* Invert Endianness    */
  106. #define _PAGE_SOFT2_4U      _AC(0x07FC000000000000,UL) /* Software bits, set 2 */
  107. #define _PAGE_RES1_4U      _AC(0x0002000000000000,UL) /* Reserved             */
  108. #define _PAGE_SZ32MB_4U      _AC(0x0001000000000000,UL) /* (Panther) 32MB page  */
  109. #define _PAGE_SZ256MB_4U  _AC(0x2001000000000000,UL) /* (Panther) 256MB page */
  110. #define _PAGE_SZALL_4U      _AC(0x6001000000000000,UL) /* All pgsz bits        */
  111. #define _PAGE_SN_4U      _AC(0x0000800000000000,UL) /* (Cheetah) Snoop      */
  112. #define _PAGE_RES2_4U      _AC(0x0000780000000000,UL) /* Reserved             */
  113. #define _PAGE_PADDR_4U      _AC(0x000007FFFFFFE000,UL) /* (Cheetah) pa[42:13]  */
  114. #define _PAGE_SOFT_4U      _AC(0x0000000000001F80,UL) /* Software bits:       */
  115. #define _PAGE_EXEC_4U      _AC(0x0000000000001000,UL) /* Executable SW bit    */
  116. #define _PAGE_MODIFIED_4U _AC(0x0000000000000800,UL) /* Modified (dirty)     */
  117. #define _PAGE_FILE_4U      _AC(0x0000000000000800,UL) /* Pagecache page       */
  118. #define _PAGE_ACCESSED_4U _AC(0x0000000000000400,UL) /* Accessed (ref'd)     */
  119. #define _PAGE_READ_4U      _AC(0x0000000000000200,UL) /* Readable SW Bit      */
  120. #define _PAGE_WRITE_4U      _AC(0x0000000000000100,UL) /* Writable SW Bit      */
  121. #define _PAGE_PRESENT_4U  _AC(0x0000000000000080,UL) /* Present              */
  122. #define _PAGE_L_4U      _AC(0x0000000000000040,UL) /* Locked TTE           */
  123. #define _PAGE_CP_4U      _AC(0x0000000000000020,UL) /* Cacheable in P-Cache */
  124. #define _PAGE_CV_4U      _AC(0x0000000000000010,UL) /* Cacheable in V-Cache */
  125. #define _PAGE_E_4U      _AC(0x0000000000000008,UL) /* side-Effect          */
  126. #define _PAGE_P_4U      _AC(0x0000000000000004,UL) /* Privileged Page      */
  127. #define _PAGE_W_4U      _AC(0x0000000000000002,UL) /* Writable             */
  128.  
  129. /* SUN4V pte bits... */
  130. #define _PAGE_NFO_4V      _AC(0x4000000000000000,UL) /* No Fault Only        */
  131. #define _PAGE_SOFT2_4V      _AC(0x3F00000000000000,UL) /* Software bits, set 2 */
  132. #define _PAGE_MODIFIED_4V _AC(0x2000000000000000,UL) /* Modified (dirty)     */
  133. #define _PAGE_ACCESSED_4V _AC(0x1000000000000000,UL) /* Accessed (ref'd)     */
  134. #define _PAGE_READ_4V      _AC(0x0800000000000000,UL) /* Readable SW Bit      */
  135. #define _PAGE_WRITE_4V      _AC(0x0400000000000000,UL) /* Writable SW Bit      */
  136. #define _PAGE_PADDR_4V      _AC(0x00FFFFFFFFFFE000,UL) /* paddr[55:13]         */
  137. #define _PAGE_IE_4V      _AC(0x0000000000001000,UL) /* Invert Endianness    */
  138. #define _PAGE_E_4V      _AC(0x0000000000000800,UL) /* side-Effect          */
  139. #define _PAGE_CP_4V      _AC(0x0000000000000400,UL) /* Cacheable in P-Cache */
  140. #define _PAGE_CV_4V      _AC(0x0000000000000200,UL) /* Cacheable in V-Cache */
  141. #define _PAGE_P_4V      _AC(0x0000000000000100,UL) /* Privileged Page      */
  142. #define _PAGE_EXEC_4V      _AC(0x0000000000000080,UL) /* Executable Page      */
  143. #define _PAGE_W_4V      _AC(0x0000000000000040,UL) /* Writable             */
  144. #define _PAGE_SOFT_4V      _AC(0x0000000000000030,UL) /* Software bits        */
  145. #define _PAGE_FILE_4V      _AC(0x0000000000000020,UL) /* Pagecache page       */
  146. #define _PAGE_PRESENT_4V  _AC(0x0000000000000010,UL) /* Present              */
  147. #define _PAGE_RESV_4V      _AC(0x0000000000000008,UL) /* Reserved             */
  148. #define _PAGE_SZ16GB_4V      _AC(0x0000000000000007,UL) /* 16GB Page            */
  149. #define _PAGE_SZ2GB_4V      _AC(0x0000000000000006,UL) /* 2GB Page             */
  150. #define _PAGE_SZ256MB_4V  _AC(0x0000000000000005,UL) /* 256MB Page           */
  151. #define _PAGE_SZ32MB_4V      _AC(0x0000000000000004,UL) /* 32MB Page            */
  152. #define _PAGE_SZ4MB_4V      _AC(0x0000000000000003,UL) /* 4MB Page             */
  153. #define _PAGE_SZ512K_4V      _AC(0x0000000000000002,UL) /* 512K Page            */
  154. #define _PAGE_SZ64K_4V      _AC(0x0000000000000001,UL) /* 64K Page             */
  155. #define _PAGE_SZ8K_4V      _AC(0x0000000000000000,UL) /* 8K Page              */
  156. #define _PAGE_SZALL_4V      _AC(0x0000000000000007,UL) /* All pgsz bits        */
  157.  
  158. #if PAGE_SHIFT == 13
  159. #define _PAGE_SZBITS_4U    _PAGE_SZ8K_4U
  160. #define _PAGE_SZBITS_4V    _PAGE_SZ8K_4V
  161. #elif PAGE_SHIFT == 16
  162. #define _PAGE_SZBITS_4U    _PAGE_SZ64K_4U
  163. #define _PAGE_SZBITS_4V    _PAGE_SZ64K_4V
  164. #else
  165. #error Wrong PAGE_SHIFT specified
  166. #endif
  167.  
  168. #if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
  169. #define _PAGE_SZHUGE_4U    _PAGE_SZ4MB_4U
  170. #define _PAGE_SZHUGE_4V    _PAGE_SZ4MB_4V
  171. #elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
  172. #define _PAGE_SZHUGE_4U    _PAGE_SZ512K_4U
  173. #define _PAGE_SZHUGE_4V    _PAGE_SZ512K_4V
  174. #elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
  175. #define _PAGE_SZHUGE_4U    _PAGE_SZ64K_4U
  176. #define _PAGE_SZHUGE_4V    _PAGE_SZ64K_4V
  177. #endif
  178.  
  179. /* These are actually filled in at boot time by sun4{u,v}_pgprot_init() */
  180. #define __P000    __pgprot(0)
  181. #define __P001    __pgprot(0)
  182. #define __P010    __pgprot(0)
  183. #define __P011    __pgprot(0)
  184. #define __P100    __pgprot(0)
  185. #define __P101    __pgprot(0)
  186. #define __P110    __pgprot(0)
  187. #define __P111    __pgprot(0)
  188.  
  189. #define __S000    __pgprot(0)
  190. #define __S001    __pgprot(0)
  191. #define __S010    __pgprot(0)
  192. #define __S011    __pgprot(0)
  193. #define __S100    __pgprot(0)
  194. #define __S101    __pgprot(0)
  195. #define __S110    __pgprot(0)
  196. #define __S111    __pgprot(0)
  197.  
  198. #ifndef __ASSEMBLY__
  199.  
  200. extern pte_t mk_pte_io(unsigned long, pgprot_t, int, unsigned long);
  201.  
  202. extern unsigned long pte_sz_bits(unsigned long size);
  203.  
  204. extern pgprot_t PAGE_KERNEL;
  205. extern pgprot_t PAGE_KERNEL_LOCKED;
  206. extern pgprot_t PAGE_COPY;
  207. extern pgprot_t PAGE_SHARED;
  208.  
  209. /* XXX This uglyness is for the atyfb driver's sparc mmap() support. XXX */
  210. extern unsigned long _PAGE_IE;
  211. extern unsigned long _PAGE_E;
  212. extern unsigned long _PAGE_CACHE;
  213.  
  214. extern unsigned long pg_iobits;
  215. extern unsigned long _PAGE_ALL_SZ_BITS;
  216. extern unsigned long _PAGE_SZBITS;
  217.  
  218. extern struct page *mem_map_zero;
  219. #define ZERO_PAGE(vaddr)    (mem_map_zero)
  220.  
  221. /* PFNs are real physical page numbers.  However, mem_map only begins to record
  222.  * per-page information starting at pfn_base.  This is to handle systems where
  223.  * the first physical page in the machine is at some huge physical address,
  224.  * such as 4GB.   This is common on a partitioned E10000, for example.
  225.  */
  226. static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
  227. {
  228.     unsigned long paddr = pfn << PAGE_SHIFT;
  229.     unsigned long sz_bits;
  230.  
  231.     sz_bits = 0UL;
  232.     if (_PAGE_SZBITS_4U != 0UL || _PAGE_SZBITS_4V != 0UL) {
  233.         __asm__ __volatile__(
  234.         "\n661:    sethi        %%uhi(%1), %0\n"
  235.         "    sllx        %0, 32, %0\n"
  236.         "    .section    .sun4v_2insn_patch, \"ax\"\n"
  237.         "    .word        661b\n"
  238.         "    mov        %2, %0\n"
  239.         "    nop\n"
  240.         "    .previous\n"
  241.         : "=r" (sz_bits)
  242.         : "i" (_PAGE_SZBITS_4U), "i" (_PAGE_SZBITS_4V));
  243.     }
  244.     return __pte(paddr | sz_bits | pgprot_val(prot));
  245. }
  246. #define mk_pte(page, pgprot)    pfn_pte(page_to_pfn(page), (pgprot))
  247.  
  248. /* This one can be done with two shifts.  */
  249. static inline unsigned long pte_pfn(pte_t pte)
  250. {
  251.     unsigned long ret;
  252.  
  253.     __asm__ __volatile__(
  254.     "\n661:    sllx        %1, %2, %0\n"
  255.     "    srlx        %0, %3, %0\n"
  256.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  257.     "    .word        661b\n"
  258.     "    sllx        %1, %4, %0\n"
  259.     "    srlx        %0, %5, %0\n"
  260.     "    .previous\n"
  261.     : "=r" (ret)
  262.     : "r" (pte_val(pte)),
  263.       "i" (21), "i" (21 + PAGE_SHIFT),
  264.       "i" (8), "i" (8 + PAGE_SHIFT));
  265.  
  266.     return ret;
  267. }
  268. #define pte_page(x) pfn_to_page(pte_pfn(x))
  269.  
  270. static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
  271. {
  272.     unsigned long mask, tmp;
  273.  
  274.     /* SUN4U: 0x600307ffffffecb8 (negated == 0x9ffcf80000001347)
  275.      * SUN4V: 0x30ffffffffffee17 (negated == 0xcf000000000011e8)
  276.      *
  277.      * Even if we use negation tricks the result is still a 6
  278.      * instruction sequence, so don't try to play fancy and just
  279.      * do the most straightforward implementation.
  280.      *
  281.      * Note: We encode this into 3 sun4v 2-insn patch sequences.
  282.      */
  283.  
  284.     __asm__ __volatile__(
  285.     "\n661:    sethi        %%uhi(%2), %1\n"
  286.     "    sethi        %%hi(%2), %0\n"
  287.     "\n662:    or        %1, %%ulo(%2), %1\n"
  288.     "    or        %0, %%lo(%2), %0\n"
  289.     "\n663:    sllx        %1, 32, %1\n"
  290.     "    or        %0, %1, %0\n"
  291.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  292.     "    .word        661b\n"
  293.     "    sethi        %%uhi(%3), %1\n"
  294.     "    sethi        %%hi(%3), %0\n"
  295.     "    .word        662b\n"
  296.     "    or        %1, %%ulo(%3), %1\n"
  297.     "    or        %0, %%lo(%3), %0\n"
  298.     "    .word        663b\n"
  299.     "    sllx        %1, 32, %1\n"
  300.     "    or        %0, %1, %0\n"
  301.     "    .previous\n"
  302.     : "=r" (mask), "=r" (tmp)
  303.     : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U |
  304.            _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_PRESENT_4U |
  305.            _PAGE_SZBITS_4U),
  306.       "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
  307.            _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_PRESENT_4V |
  308.            _PAGE_SZBITS_4V));
  309.  
  310.     return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask));
  311. }
  312.  
  313. static inline pte_t pgoff_to_pte(unsigned long off)
  314. {
  315.     off <<= PAGE_SHIFT;
  316.  
  317.     __asm__ __volatile__(
  318.     "\n661:    or        %0, %2, %0\n"
  319.     "    .section    .sun4v_1insn_patch, \"ax\"\n"
  320.     "    .word        661b\n"
  321.     "    or        %0, %3, %0\n"
  322.     "    .previous\n"
  323.     : "=r" (off)
  324.     : "0" (off), "i" (_PAGE_FILE_4U), "i" (_PAGE_FILE_4V));
  325.  
  326.     return __pte(off);
  327. }
  328.  
  329. static inline pgprot_t pgprot_noncached(pgprot_t prot)
  330. {
  331.     unsigned long val = pgprot_val(prot);
  332.  
  333.     __asm__ __volatile__(
  334.     "\n661:    andn        %0, %2, %0\n"
  335.     "    or        %0, %3, %0\n"
  336.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  337.     "    .word        661b\n"
  338.     "    andn        %0, %4, %0\n"
  339.     "    or        %0, %5, %0\n"
  340.     "    .previous\n"
  341.     : "=r" (val)
  342.     : "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U),
  343.                  "i" (_PAGE_CP_4V | _PAGE_CV_4V), "i" (_PAGE_E_4V));
  344.  
  345.     return __pgprot(val);
  346. }
  347. /* Various pieces of code check for platform support by ifdef testing
  348.  * on "pgprot_noncached".  That's broken and should be fixed, but for
  349.  * now...
  350.  */
  351. #define pgprot_noncached pgprot_noncached
  352.  
  353. #ifdef CONFIG_HUGETLB_PAGE
  354. static inline pte_t pte_mkhuge(pte_t pte)
  355. {
  356.     unsigned long mask;
  357.  
  358.     __asm__ __volatile__(
  359.     "\n661:    sethi        %%uhi(%1), %0\n"
  360.     "    sllx        %0, 32, %0\n"
  361.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  362.     "    .word        661b\n"
  363.     "    mov        %2, %0\n"
  364.     "    nop\n"
  365.     "    .previous\n"
  366.     : "=r" (mask)
  367.     : "i" (_PAGE_SZHUGE_4U), "i" (_PAGE_SZHUGE_4V));
  368.  
  369.     return __pte(pte_val(pte) | mask);
  370. }
  371. #endif
  372.  
  373. static inline pte_t pte_mkdirty(pte_t pte)
  374. {
  375.     unsigned long val = pte_val(pte), tmp;
  376.  
  377.     __asm__ __volatile__(
  378.     "\n661:    or        %0, %3, %0\n"
  379.     "    nop\n"
  380.     "\n662:    nop\n"
  381.     "    nop\n"
  382.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  383.     "    .word        661b\n"
  384.     "    sethi        %%uhi(%4), %1\n"
  385.     "    sllx        %1, 32, %1\n"
  386.     "    .word        662b\n"
  387.     "    or        %1, %%lo(%4), %1\n"
  388.     "    or        %0, %1, %0\n"
  389.     "    .previous\n"
  390.     : "=r" (val), "=r" (tmp)
  391.     : "0" (val), "i" (_PAGE_MODIFIED_4U | _PAGE_W_4U),
  392.       "i" (_PAGE_MODIFIED_4V | _PAGE_W_4V));
  393.  
  394.     return __pte(val);
  395. }
  396.  
  397. static inline pte_t pte_mkclean(pte_t pte)
  398. {
  399.     unsigned long val = pte_val(pte), tmp;
  400.  
  401.     __asm__ __volatile__(
  402.     "\n661:    andn        %0, %3, %0\n"
  403.     "    nop\n"
  404.     "\n662:    nop\n"
  405.     "    nop\n"
  406.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  407.     "    .word        661b\n"
  408.     "    sethi        %%uhi(%4), %1\n"
  409.     "    sllx        %1, 32, %1\n"
  410.     "    .word        662b\n"
  411.     "    or        %1, %%lo(%4), %1\n"
  412.     "    andn        %0, %1, %0\n"
  413.     "    .previous\n"
  414.     : "=r" (val), "=r" (tmp)
  415.     : "0" (val), "i" (_PAGE_MODIFIED_4U | _PAGE_W_4U),
  416.       "i" (_PAGE_MODIFIED_4V | _PAGE_W_4V));
  417.  
  418.     return __pte(val);
  419. }
  420.  
  421. static inline pte_t pte_mkwrite(pte_t pte)
  422. {
  423.     unsigned long val = pte_val(pte), mask;
  424.  
  425.     __asm__ __volatile__(
  426.     "\n661:    mov        %1, %0\n"
  427.     "    nop\n"
  428.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  429.     "    .word        661b\n"
  430.     "    sethi        %%uhi(%2), %0\n"
  431.     "    sllx        %0, 32, %0\n"
  432.     "    .previous\n"
  433.     : "=r" (mask)
  434.     : "i" (_PAGE_WRITE_4U), "i" (_PAGE_WRITE_4V));
  435.  
  436.     return __pte(val | mask);
  437. }
  438.  
  439. static inline pte_t pte_wrprotect(pte_t pte)
  440. {
  441.     unsigned long val = pte_val(pte), tmp;
  442.  
  443.     __asm__ __volatile__(
  444.     "\n661:    andn        %0, %3, %0\n"
  445.     "    nop\n"
  446.     "\n662:    nop\n"
  447.     "    nop\n"
  448.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  449.     "    .word        661b\n"
  450.     "    sethi        %%uhi(%4), %1\n"
  451.     "    sllx        %1, 32, %1\n"
  452.     "    .word        662b\n"
  453.     "    or        %1, %%lo(%4), %1\n"
  454.     "    andn        %0, %1, %0\n"
  455.     "    .previous\n"
  456.     : "=r" (val), "=r" (tmp)
  457.     : "0" (val), "i" (_PAGE_WRITE_4U | _PAGE_W_4U),
  458.       "i" (_PAGE_WRITE_4V | _PAGE_W_4V));
  459.  
  460.     return __pte(val);
  461. }
  462.  
  463. static inline pte_t pte_mkold(pte_t pte)
  464. {
  465.     unsigned long mask;
  466.  
  467.     __asm__ __volatile__(
  468.     "\n661:    mov        %1, %0\n"
  469.     "    nop\n"
  470.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  471.     "    .word        661b\n"
  472.     "    sethi        %%uhi(%2), %0\n"
  473.     "    sllx        %0, 32, %0\n"
  474.     "    .previous\n"
  475.     : "=r" (mask)
  476.     : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V));
  477.  
  478.     mask |= _PAGE_R;
  479.  
  480.     return __pte(pte_val(pte) & ~mask);
  481. }
  482.  
  483. static inline pte_t pte_mkyoung(pte_t pte)
  484. {
  485.     unsigned long mask;
  486.  
  487.     __asm__ __volatile__(
  488.     "\n661:    mov        %1, %0\n"
  489.     "    nop\n"
  490.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  491.     "    .word        661b\n"
  492.     "    sethi        %%uhi(%2), %0\n"
  493.     "    sllx        %0, 32, %0\n"
  494.     "    .previous\n"
  495.     : "=r" (mask)
  496.     : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V));
  497.  
  498.     mask |= _PAGE_R;
  499.  
  500.     return __pte(pte_val(pte) | mask);
  501. }
  502.  
  503. static inline pte_t pte_mkspecial(pte_t pte)
  504. {
  505.     return pte;
  506. }
  507.  
  508. static inline unsigned long pte_young(pte_t pte)
  509. {
  510.     unsigned long mask;
  511.  
  512.     __asm__ __volatile__(
  513.     "\n661:    mov        %1, %0\n"
  514.     "    nop\n"
  515.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  516.     "    .word        661b\n"
  517.     "    sethi        %%uhi(%2), %0\n"
  518.     "    sllx        %0, 32, %0\n"
  519.     "    .previous\n"
  520.     : "=r" (mask)
  521.     : "i" (_PAGE_ACCESSED_4U), "i" (_PAGE_ACCESSED_4V));
  522.  
  523.     return (pte_val(pte) & mask);
  524. }
  525.  
  526. static inline unsigned long pte_dirty(pte_t pte)
  527. {
  528.     unsigned long mask;
  529.  
  530.     __asm__ __volatile__(
  531.     "\n661:    mov        %1, %0\n"
  532.     "    nop\n"
  533.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  534.     "    .word        661b\n"
  535.     "    sethi        %%uhi(%2), %0\n"
  536.     "    sllx        %0, 32, %0\n"
  537.     "    .previous\n"
  538.     : "=r" (mask)
  539.     : "i" (_PAGE_MODIFIED_4U), "i" (_PAGE_MODIFIED_4V));
  540.  
  541.     return (pte_val(pte) & mask);
  542. }
  543.  
  544. static inline unsigned long pte_write(pte_t pte)
  545. {
  546.     unsigned long mask;
  547.  
  548.     __asm__ __volatile__(
  549.     "\n661:    mov        %1, %0\n"
  550.     "    nop\n"
  551.     "    .section    .sun4v_2insn_patch, \"ax\"\n"
  552.     "    .word        661b\n"
  553.     "    sethi        %%uhi(%2), %0\n"
  554.     "    sllx        %0, 32, %0\n"
  555.     "    .previous\n"
  556.     : "=r" (mask)
  557.     : "i" (_PAGE_WRITE_4U), "i" (_PAGE_WRITE_4V));
  558.  
  559.     return (pte_val(pte) & mask);
  560. }
  561.  
  562. static inline unsigned long pte_exec(pte_t pte)
  563. {
  564.     unsigned long mask;
  565.  
  566.     __asm__ __volatile__(
  567.     "\n661:    sethi        %%hi(%1), %0\n"
  568.     "    .section    .sun4v_1insn_patch, \"ax\"\n"
  569.     "    .word        661b\n"
  570.     "    mov        %2, %0\n"
  571.     "    .previous\n"
  572.     : "=r" (mask)
  573.     : "i" (_PAGE_EXEC_4U), "i" (_PAGE_EXEC_4V));
  574.  
  575.     return (pte_val(pte) & mask);
  576. }
  577.  
  578. static inline unsigned long pte_file(pte_t pte)
  579. {
  580.     unsigned long val = pte_val(pte);
  581.  
  582.     __asm__ __volatile__(
  583.     "\n661:    and        %0, %2, %0\n"
  584.     "    .section    .sun4v_1insn_patch, \"ax\"\n"
  585.     "    .word        661b\n"
  586.     "    and        %0, %3, %0\n"
  587.     "    .previous\n"
  588.     : "=r" (val)
  589.     : "0" (val), "i" (_PAGE_FILE_4U), "i" (_PAGE_FILE_4V));
  590.  
  591.     return val;
  592. }
  593.  
  594. static inline unsigned long pte_present(pte_t pte)
  595. {
  596.     unsigned long val = pte_val(pte);
  597.  
  598.     __asm__ __volatile__(
  599.     "\n661:    and        %0, %2, %0\n"
  600.     "    .section    .sun4v_1insn_patch, \"ax\"\n"
  601.     "    .word        661b\n"
  602.     "    and        %0, %3, %0\n"
  603.     "    .previous\n"
  604.     : "=r" (val)
  605.     : "0" (val), "i" (_PAGE_PRESENT_4U), "i" (_PAGE_PRESENT_4V));
  606.  
  607.     return val;
  608. }
  609.  
  610. static inline int pte_special(pte_t pte)
  611. {
  612.     return 0;
  613. }
  614.  
  615. #define pmd_set(pmdp, ptep)    \
  616.     (pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL))
  617. #define pud_set(pudp, pmdp)    \
  618.     (pud_val(*(pudp)) = (__pa((unsigned long) (pmdp)) >> 11UL))
  619. #define __pmd_page(pmd)        \
  620.     ((unsigned long) __va((((unsigned long)pmd_val(pmd))<<11UL)))
  621. #define pmd_page(pmd)             virt_to_page((void *)__pmd_page(pmd))
  622. #define pud_page_vaddr(pud)        \
  623.     ((unsigned long) __va((((unsigned long)pud_val(pud))<<11UL)))
  624. #define pud_page(pud)             virt_to_page((void *)pud_page_vaddr(pud))
  625. #define pmd_none(pmd)            (!pmd_val(pmd))
  626. #define pmd_bad(pmd)            (0)
  627. #define pmd_present(pmd)        (pmd_val(pmd) != 0U)
  628. #define pmd_clear(pmdp)            (pmd_val(*(pmdp)) = 0U)
  629. #define pud_none(pud)            (!pud_val(pud))
  630. #define pud_bad(pud)            (0)
  631. #define pud_present(pud)        (pud_val(pud) != 0U)
  632. #define pud_clear(pudp)            (pud_val(*(pudp)) = 0U)
  633.  
  634. /* Same in both SUN4V and SUN4U.  */
  635. #define pte_none(pte)             (!pte_val(pte))
  636.  
  637. /* to find an entry in a page-table-directory. */
  638. #define pgd_index(address)    (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
  639. #define pgd_offset(mm, address)    ((mm)->pgd + pgd_index(address))
  640.  
  641. /* to find an entry in a kernel page-table-directory */
  642. #define pgd_offset_k(address) pgd_offset(&init_mm, address)
  643.  
  644. /* Find an entry in the second-level page table.. */
  645. #define pmd_offset(pudp, address)    \
  646.     ((pmd_t *) pud_page_vaddr(*(pudp)) + \
  647.      (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)))
  648.  
  649. /* Find an entry in the third-level page table.. */
  650. #define pte_index(dir, address)    \
  651.     ((pte_t *) __pmd_page(*(dir)) + \
  652.      ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
  653. #define pte_offset_kernel        pte_index
  654. #define pte_offset_map            pte_index
  655. #define pte_offset_map_nested        pte_index
  656. #define pte_unmap(pte)            do { } while (0)
  657. #define pte_unmap_nested(pte)        do { } while (0)
  658.  
  659. /* Actual page table PTE updates.  */
  660. extern void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t orig);
  661.  
  662. static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
  663. {
  664.     pte_t orig = *ptep;
  665.  
  666.     *ptep = pte;
  667.  
  668.     /* It is more efficient to let flush_tlb_kernel_range()
  669.      * handle init_mm tlb flushes.
  670.      *
  671.      * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
  672.      *             and SUN4V pte layout, so this inline test is fine.
  673.      */
  674.     if (likely(mm != &init_mm) && (pte_val(orig) & _PAGE_VALID))
  675.         tlb_batch_add(mm, addr, ptep, orig);
  676. }
  677.  
  678. #define pte_clear(mm,addr,ptep)        \
  679.     set_pte_at((mm), (addr), (ptep), __pte(0UL))
  680.  
  681. #ifdef DCACHE_ALIASING_POSSIBLE
  682. #define __HAVE_ARCH_MOVE_PTE
  683. #define move_pte(pte, prot, old_addr, new_addr)                \
  684. ({                                    \
  685.     pte_t newpte = (pte);                        \
  686.     if (tlb_type != hypervisor && pte_present(pte)) {        \
  687.         unsigned long this_pfn = pte_pfn(pte);            \
  688.                                     \
  689.         if (pfn_valid(this_pfn) &&                \
  690.             (((old_addr) ^ (new_addr)) & (1 << 13)))        \
  691.             flush_dcache_page_all(current->mm,        \
  692.                           pfn_to_page(this_pfn));    \
  693.     }                                \
  694.     newpte;                                \
  695. })
  696. #endif
  697.  
  698. extern pgd_t swapper_pg_dir[2048];
  699. extern pmd_t swapper_low_pmd_dir[2048];
  700.  
  701. extern void paging_init(void);
  702. extern unsigned long find_ecache_flush_span(unsigned long size);
  703.  
  704. /* These do nothing with the way I have things setup. */
  705. #define mmu_lockarea(vaddr, len)        (vaddr)
  706. #define mmu_unlockarea(vaddr, len)        do { } while(0)
  707.  
  708. struct vm_area_struct;
  709. extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
  710.  
  711. /* Encode and de-code a swap entry */
  712. #define __swp_type(entry)    (((entry).val >> PAGE_SHIFT) & 0xffUL)
  713. #define __swp_offset(entry)    ((entry).val >> (PAGE_SHIFT + 8UL))
  714. #define __swp_entry(type, offset)    \
  715.     ( (swp_entry_t) \
  716.       { \
  717.         (((long)(type) << PAGE_SHIFT) | \
  718.                  ((long)(offset) << (PAGE_SHIFT + 8UL))) \
  719.       } )
  720. #define __pte_to_swp_entry(pte)        ((swp_entry_t) { pte_val(pte) })
  721. #define __swp_entry_to_pte(x)        ((pte_t) { (x).val })
  722.  
  723. /* File offset in PTE support. */
  724. extern unsigned long pte_file(pte_t);
  725. #define pte_to_pgoff(pte)    (pte_val(pte) >> PAGE_SHIFT)
  726. extern pte_t pgoff_to_pte(unsigned long);
  727. #define PTE_FILE_MAX_BITS    (64UL - PAGE_SHIFT - 1UL)
  728.  
  729. extern unsigned long *sparc64_valid_addr_bitmap;
  730.  
  731. /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
  732. #define kern_addr_valid(addr)    \
  733.     (test_bit(__pa((unsigned long)(addr))>>22, sparc64_valid_addr_bitmap))
  734.  
  735. extern int page_in_phys_avail(unsigned long paddr);
  736.  
  737. extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
  738.                    unsigned long pfn,
  739.                    unsigned long size, pgprot_t prot);
  740.  
  741. /*
  742.  * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
  743.  * its high 4 bits.  These macros/functions put it there or get it from there.
  744.  */
  745. #define MK_IOSPACE_PFN(space, pfn)    (pfn | (space << (BITS_PER_LONG - 4)))
  746. #define GET_IOSPACE(pfn)        (pfn >> (BITS_PER_LONG - 4))
  747. #define GET_PFN(pfn)            (pfn & 0x0fffffffffffffffUL)
  748.  
  749. #include <asm-generic/pgtable.h>
  750.  
  751. /* We provide our own get_unmapped_area to cope with VA holes and
  752.  * SHM area cache aliasing for userland.
  753.  */
  754. #define HAVE_ARCH_UNMAPPED_AREA
  755. #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
  756.  
  757. /* We provide a special get_unmapped_area for framebuffer mmaps to try and use
  758.  * the largest alignment possible such that larget PTEs can be used.
  759.  */
  760. extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long,
  761.                       unsigned long, unsigned long,
  762.                       unsigned long);
  763. #define HAVE_ARCH_FB_UNMAPPED_AREA
  764.  
  765. extern void pgtable_cache_init(void);
  766. extern void sun4v_register_fault_status(void);
  767. extern void sun4v_ktsb_register(void);
  768. extern void __init cheetah_ecache_flush_init(void);
  769. extern void sun4v_patch_tlb_handlers(void);
  770.  
  771. extern unsigned long cmdline_memory_size;
  772.  
  773. extern asmlinkage void do_sparc64_fault(struct pt_regs *regs);
  774.  
  775. #endif /* !(__ASSEMBLY__) */
  776.  
  777. #endif /* !(_SPARC64_PGTABLE_H) */
  778.